package com.atguigu.interview.juc;

import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

/**
 * @Author : Jungle
 * @Description :
 * 可重入锁:可重复可递归调用的锁，在外层使用锁之后，在内层仍然可以使用，并且室发生死锁，这样的锁就叫做可重入锁。
 * 在一个synchronized修饰的方法或代码块的内部
 * 调用本类的其他synchronized 修饰的方法或代码块时，是永远可以得到锁的
 *
 *    显示调用
 */
public class ReenterLockDemo3 {
   static Lock lock = new ReentrantLock();


    public static void main(String[] args) {
        m1();
    }


    /**
     * 1、同步代码块
     */
    private static void m1() {
        new Thread(() -> {
            lock.lock();
            lock.lock();
            try {
                System.out.println("=======外层");
                //正常情况这里需要释放锁，但是因为是重入锁，可以在后面解锁
                lock.lock();
                try {
                    System.out.println("=======中层");
                    lock.lock();
                    try {
                        System.out.println("=======内层");
                    } catch (Exception e) {
                       
                    } finally {
                        lock.unlock();
                    }
                } catch (Exception e) {
                   
                } finally {
                    lock.unlock();
                }
            } catch (Exception e) {
               
            } finally {
                //实现加锁次数和释放次数不一样
                //由于加锁次数和释放次数不一样，第二个线程始终无法获取到锁，导致一直在等待。
                lock.unlock();
                lock.unlock();
            }
        }, "t1").start();





        new Thread(() -> {
            lock.lock();
            try {
                System.out.println(Thread.currentThread().getName()+"\t 调用开始");
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                lock.unlock();
            }

        }, "t2").start();
    }


}
